#include <pthread.h>
#include <iostream>
#include <functional>
#include <string>
using namespace std;

// //传参数模式
// template<class T>
// class Thread
// {
//     enum class TSTATUS
//     {
//         NEW,
//         RUNNING,
//         STOP
//     };
//     using func = std::function<void(T&)>;
//     static void* routine(void* args){
//         Thread* t = static_cast<Thread*>(args);
//         t->_status = TSTATUS::RUNNING;
//         cout << "开始执行任务" << endl;
//         t->_func(t->_data);
//         return nullptr;
//     }
// public:
//     Thread(func f,T& data)
//         :_func(f),
//         _isjoinable(true),
//         _status(TSTATUS::NEW),
//         _data(data)
//         {}
//     bool Start(){
//         if (_status == TSTATUS::NEW){
//             int n = pthread_create(&_pid,nullptr,routine,this);
//             if (n < 0){
//                 perror("创建进程失败");
//                 return false;
//             }
//             return true;
//         }
//         else {
//             cout << "pthread状态不是最新" << endl;
//             return false;
//         }
//     }
//     bool Stop(){
//         if (_status == TSTATUS::RUNNING){
//             int n = pthread_cancel(_pid);
//             if (n < 0){
//                 perror("pthread_cancel error");
//                 return false;
//             }
//             return true;
//         }
//         else {
//             cout << "请启动线程" << endl;
//             return false;
//         }
//     }
//     bool Join(){
//         int n = pthread_join(_pid,nullptr);
//         if (n == 0){
//             cout << "等待线程成功" << endl;
//             return true;
//         }
//         else {
//             cout << "等待线程失败" << endl;
//             return false;
//         }
//     }
//     bool Detach(){
//         int n = pthread_detach(_pid);
//         if (n == 0){
//             cout << "分离成功" << endl;
//             return true;
//         }
//         else {
//             cout << "分离失败" << endl;
//             return false;
//         }
//     }
//     bool IsJoinbale(){return _isjoinable;}
//     void EnableDetech(){_isjoinable = false;}

// private:
//     T _data;
//     func _func;
//     pthread_t _pid;
//     TSTATUS _status;
//     bool _isjoinable;
// };


//无参数模式
class Thread
{
    enum class TSTATUS
    {
        NEW,
        RUNNING,
        STOP
    };
    using func = std::function<void()>;
    static void* routine(void* args){
        Thread* t = static_cast<Thread*>(args);
        t->_status = TSTATUS::RUNNING;
        t->_func();
        return nullptr;
    }
public:
    Thread(func f,const std::string& name="thread")
        :_name(name),
        _func(f),
        _isjoinable(true),
        _status(TSTATUS::NEW)
        {}
    bool Start(){
        if (_status == TSTATUS::NEW){
            int n = pthread_create(&_pid,nullptr,routine,this);
            if (n < 0){
                perror("创建进程失败");
                return false;
            }
            return true;
        }
        else {
            cout << "pthread状态不是最新" << endl;
            return false;
        }
    }
    bool Stop(){
        if (_status == TSTATUS::RUNNING){
            int n = pthread_cancel(_pid);
            if (n < 0){
                perror("pthread_cancel error");
                return false;
            }
            return true;
        }
        else {
            cout << "请启动线程" << endl;
            return false;
        }
    }
    bool Join(){
        int n = pthread_join(_pid,nullptr);
        if (n == 0){
            cout << "等待线程成功" << endl;
            return true;
        }
        else {
            cout << "等待线程失败" << endl;
            return false;
        }
    }
    bool Detach(){
        int n = pthread_detach(_pid);
        if (n == 0){
            cout << "分离成功" << endl;
            return true;
        }
        else {
            cout << "分离失败" << endl;
            return false;
        }
    }
    bool IsJoinbale(){return _isjoinable;}
    void EnableDetech(){_isjoinable = false;}

private:
    std::string _name;
    func _func;
    pthread_t _pid;
    TSTATUS _status;
    bool _isjoinable;
};